const dictionary = require('../conf/dictionary.json')
const conf = require('../conf/conf.json')

class Display {
    constructor(value, rendered) {
        this._og = value
        this._out = rendered
    }

    get og() {
        return this._og
    }

    get out() {
        return this._out
    }

    toString() {
        return this._out.toString()
    }

    static unitAny = (v, u) => isNaN(v) ? null : new Display(v, `${v}${u}`)
    static percent = v => new Display(v, `${v * 100}%`)
    static additive = v => new Display(v, `+${v}`)
    static additivePercent = v => new Display(v, (v > 0 ? '+' : '') + `${v * 100}%`)
    static multiplier = v => new Display(v, `×${v}`)
    static multiplierPercent = v => new Display(v, `×${v * 100}%`)
    static time = v => this.unitAny(v, 's')
    static angle = v => this.unitAny(v, '°')
    static code = v => new Display(v, `<code>${v}</code>`)
    static tag = this.code
    static mutationId = this.code
    static overrideLifespan = (og, life) => !og ? Display.time(life) : (isNaN(life) ? null : Display.time(Math.min(og.og, life)))
}

const translateKey = (obj) => {
    if (typeof obj !== 'object' || obj === null) {
        return obj
    }

    if (Array.isArray(obj)) {
        return obj.map(translateKey);
    }

    if (obj instanceof Display) {
        return obj.out
    }

    const converted = {};

    Object.keys(obj).forEach(oldKey => {
        const newKey = dictionary.key[oldKey] || oldKey;
        converted[newKey] = translateKey(obj[oldKey]);
    });

    return converted;
}

const translateValue = (key, def, ...params) => {
    return conf.translate && dictionary.misc[key] ? dictionary.misc[key].format(...params) : def
}

const translateTower = (key) => {
    return conf.translate && dictionary.tower[key] ? dictionary.tower[key] : key
}

const translateBloon = (key) => {
    return conf.translate && dictionary.bloon[key.toLowerCase()] ? dictionary.bloon[key.toLowerCase()] : Display.tag(key)
}

const translateAreaType = (key) => {
    return conf.translate && dictionary.area[key.toLowerCase()] ? dictionary.area[key.toLowerCase()] : key
}

const translateGeraldoItem = (key) => {
    return conf.translate && dictionary.geraldoItems[key] ? dictionary.geraldoItems[key] : key
}

const translateCorvusSpells = (key) => {
    return conf.translate && dictionary.corvusSpells[key] ? dictionary.corvusSpells[key] : key
}

const translateProjectile = (key) => {
    return conf.translate && dictionary.projectile[key] ? dictionary.projectile[key] : key
}

const translateAttack = (key) => {
    return conf.translate && dictionary.attack[key] ? dictionary.attack[key] : key
}

const translateAbility = (key) => {
    return conf.translate && dictionary.ability[key] ? dictionary.ability[key] : key
}

const damageModValue = (add, mul) => {
    const mods = []
    if (add !== 0) {
        mods.push(Display.additive(add))
    }
    if (mul !== 1) {
        mods.push(Display.multiplier(mul))
    }
    return mods.join('/')
}

module.exports = {
    Display,
    translateKey,
    translateValue,
    translateTower,
    translateBloon,
    translateAreaType,
    translateProjectile,
    translateAttack,
    translateAbility,
    translateGeraldoItem,
    translateCorvusSpells,
    damageModValue
}